
class Main extends eui.UILayer {


    protected createChildren(): void {
        super.createChildren();

        let assetAdapter = new AssetAdapter();
        egret.registerImplementation("eui.IAssetAdapter", assetAdapter);
        egret.registerImplementation("eui.IThemeAdapter", new ThemeAdapter());


        this.runGame().catch(e => {
            console.log(e);
        })
    }

    private async runGame() {
        await this.loadResource()
        this.createGameScene();
    }

    private async loadResource() {
        try {
            const loadingView = new LoadingUI();
            this.stage.addChild(loadingView);
            await RES.loadConfig("resource/default.res.json", "resource/");
            await this.loadTheme();
            await RES.loadGroup("preload", 0, loadingView);
            this.stage.removeChild(loadingView);
        }
        catch (e) {
            console.error(e);
        }
    }

    private loadTheme() {
        return new Promise((resolve, reject) => {
            let theme = new eui.Theme("resource/default.thm.json", this.stage);
            theme.addEventListener(eui.UIEvent.COMPLETE, () => {
                resolve();
            }, this);

        })
    }

    protected createGameScene(): void {
        let sky = new egret.Bitmap();
        sky.texture = RES.getRes("bg_jpg");
        this.addChild(sky);
        let stageW = this.stage.stageWidth;
        let stageH = this.stage.stageHeight;
        sky.width = stageW;
        sky.height = stageH;

        let topMask = new egret.Shape();
        topMask.graphics.beginFill(0x000000, 0.6);
        topMask.graphics.drawRect(0, 0, stageW, 172);
        topMask.graphics.endFill();
        topMask.y = 33;
        this.addChild(topMask);

        let brickMask = new egret.Shape();
        brickMask.graphics.beginFill(0x000000, 0.7);
        brickMask.graphics.drawRect(10, 0, stageW - 20, 200);
        brickMask.graphics.endFill();
        brickMask.y = 840;
        this.addChild(brickMask);

        let title = new egret.TextField();
        title.text = "方块消除";
        title.size = 42;
        title.x = 250;
        title.y = 80;
        this.addChild(title);

        let startBt = new eui.Button();
        startBt.label = "重新开始";
        startBt.x = 280;
        startBt.y = 150;
        startBt.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onStartBtClick, this);
        this.addChild(startBt);

        let s = new egret.TextField();
        s.text = "得分：";
        s.x = 420;
        s.y = 150;
        this.addChild(s);

        this._score = new egret.TextField();
        this._score.text = "0";
        this._score.x = 520;
        this._score.y = 150;
        this.addChild(this._score);


        this.bd = new Board();
        this.bd.x = 20;
        this.bd.y = 220;
        this.addChild(this.bd);

        this.info.x = 70;
        this.info.y = 270;
        this.addChild(this.info);

        let shp = new egret.Shape();
        shp.graphics.lineStyle(8, 0x333333);
        shp.graphics.drawRect(16, 216, 608, 608);
        this.addChild(shp);

        this.shadow = new Brick(0, [], true);
        this.shadow.x = -500;
        this.addChild(this.shadow);
 
        for (let i = 0; i < 3; i++) {
            this._stageBricks[i] = new StageBrick();
            this.addChild(this._stageBricks[i].brick);
            this.addChild(this._stageBricks[i].mark);

            this._stageBricks[i].brick.touchEnabled = true;
            this._stageBricks[i].brick.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.mouseDown, this);
        }
        this.resetBricks();
        
        this.stage.addEventListener(egret.TouchEvent.TOUCH_END, this.mouseUp, this);
 
    }

    private onStartBtClick(e: egret.TouchEvent) {
        this.Score = 0;
        this.info.clear();
        this.bd.reset();
        this.resetBricks();

    }

    private bd: Board; 
    private info:InfoPanel = new InfoPanel();
    private brick: Brick = new Brick();
 

    private _stageBricks: StageBrick[] = new Array(3);

    private shadow: Brick;
    private _curBrickX: number;
    private _curBrickY: number;
    private _touchStatus: boolean = false;              //当前触摸状态，按下时，值为true
    private _distance: egret.Point = new egret.Point();


    private _score: egret.TextField;
    private _lastCol: number;
    private _lastRow: number;
    private _brickNum: number;

    get Score(): number { return parseInt(this._score.text); }
    set Score(score: number) { this._score.text = score.toString(); }
    get col() { return this._lastCol; }
    set col(idx: number) { this._lastCol = idx; }
    get row() { return this._lastRow; }
    set row(idx: number) { this._lastRow = idx; }
    get BrickNum() { return this._brickNum; }
    set BrickNum(num: number) {
        this._brickNum = num;
        if (num == 0) this.resetBricks()
    }

    /**
     * 更新游戏状态
     */
    private updateStatus() {
        let placableBrickCnt = 0;
        for (let i = 0; i < 3; i++) {
            let stageBrick = this._stageBricks[i];

            if (stageBrick.status != BrickStatus.Placed) {
                if (this.bd.isPlacable(stageBrick.brick)) {
                    stageBrick.mark.drawTick();
                    stageBrick.status = BrickStatus.Placeable;
                    stageBrick.brick.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.mouseDown, this);
        
                    placableBrickCnt++;
                } else {
                    stageBrick.mark.drawError();
                    stageBrick.status = BrickStatus.Forbidden;
                    stageBrick.brick.removeEventListener(egret.TouchEvent.TOUCH_BEGIN,this.mouseDown,this);

                }
            } else {
                stageBrick.mark.draw();
            }
        }
        if(placableBrickCnt === 0) {
            this.info.draw("游戏结束!");
        }
        
    }

    private resetBricks() {
        this.BrickNum = 3; 

        for (let i = 0; i < 3; i++) {
            this._stageBricks[i].brick.color = randomColor();
            this._stageBricks[i].brick.Shape = randomShape();
            this._stageBricks[i].brick.x = 100 + 200 * i;
            this._stageBricks[i].brick.y = 850;
            this._stageBricks[i].brick.scaleX = 0.5;
            this._stageBricks[i].brick.scaleY = 0.5;
            this._stageBricks[i].brick.draw();

            this._stageBricks[i].mark.x = 150 + 200 * i;
            this._stageBricks[i].mark.y = 980;
            this._stageBricks[i].status = BrickStatus.Placeable;

        }
 

        this.updateStatus();
    }
    private mouseDown(evt: egret.TouchEvent) { 
        let brick = evt.currentTarget as Brick;
        this.brick = brick;

        this._touchStatus = true;
        
        brick.y -= 200;
        this._distance.x = evt.stageX - brick.x;
        this._distance.y = evt.stageY - brick.y;

        this._curBrickX = brick.x;
        this._curBrickY = brick.y + 200;

        brick.scaleX = brick.scaleY = 1;
        this.setChildIndex(brick, this.numChildren - 1)

        this.shadow.Shape = brick.Shape;
        this.shadow.draw();

        this.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.mouseMove, this);
    }

    isPlacable: boolean;

    private mouseMove(evt: egret.TouchEvent) {
        let brick = this.brick;
        if (this._touchStatus) {
            let x = evt.stageX - this._distance.x;
            let y = evt.stageY - this._distance.y;
            if (x > this.bd.x && x < this.bd.x + 570
                && y > this.bd.y && y < this.bd.y + 570) {

                this.col = Math.round((x - this.bd.x) / 60);
                this.row = Math.round((y - this.bd.y) / 60);

                this.isPlacable = this.bd.tryPlace(this.row, this.col, brick);
                if (this.isPlacable) {
                    this.shadow.x = this.col * Squar.len + this.bd.x;
                    this.shadow.y = this.row * Squar.len + this.bd.y;
                } else {
                    this.shadow.x = -500;
                }

            }
            brick.x = x;
            brick.y = y;
        }
    }


    private mouseUp(evt: egret.TouchEvent) { 
        this._touchStatus = false;
        this.stage.removeEventListener(egret.TouchEvent.TOUCH_MOVE, this.mouseMove, this);

        let scores = [0, 100, 300, 500, 800, 1000]
        let brick = this.brick;
        let index = 0;
        for(let i=0;i<3;i++){
            if(brick == this._stageBricks[i].brick){
                index = i;
                break;
            }
        }
        if (brick) {
            brick.x = this._curBrickX;
            brick.y = this._curBrickY;
            brick.scaleX = brick.scaleY = 0.5;

            if (this.isPlacable) {
                let erasecnt = this.bd.place(this.row, this.col, this.brick);
                this.Score += scores[erasecnt];

                this._stageBricks[index].status = BrickStatus.Placed; 
                brick.x = -500;
                this.BrickNum--;
                
                this.updateStatus();
                this.isPlacable = false;
            }

            this.shadow.x = -500;
        }
        this.brick = null;
    }



}
